angular.module('app')
	.service('AppUiService',['$q', 'Dictionary', 'httpWrapService', function($q, Dictionary, httpWrapService){
		var app = this;
		this.getDicts = function(dictType){
			if(!Dictionary || !Dictionary.DictionaryItems) return [];
			return Dictionary.DictionaryItems[dictType];
		}
		
		this.initModel = function(scope) {
			var selected = null;
			 if(scope.model && !scope.multiple) {
				 for(var index in scope.data) {
					 var row = scope.data[index];
					 if(row[scope.valKey] == scope.model) {
						 selected = row;
						 break;
					 }
				 }
			 } else if(scope.model && scope.multiple) {
				 selected = [];
				 var strs = angular.isString(scope.model) ? scope.model.split(scope.separator) : scope.model;
				 for(var index in scope.data) {
					 var row = scope.data[index];
					 for(var i in strs) {
						 if(row[scope.valKey] == strs[i]) {
							 selected.push(row);
							 break;
						 }
					 }
				 }
			 }
			 return selected;
		}
		this.initData = function(scope, datas){
			for(var index in datas) {
				var row = datas[index];
				row._fieldText = row[scope.showKey];
			}
			return datas;
		}
		this.getDatas = function(scope) {
			var deferred = $q.defer();
			var arg = $.extend(true, {status: '1'}, scope.args);
			if(scope.url) {
				httpWrapService.post(scope.url, arg).then(function(res){
					if(res.data && res.data.data) deferred.resolve(app.initData(scope, res.data.data));
				});
			} else if(scope.dictType){
				var datas = app.getDicts(scope.dictType);
				deferred.resolve(app.initData(scope, datas));
			}
			return deferred.promise;
		}
		
		this.showText = function(scope, obj) {
			var text;
			if(angular.isArray(obj)) {
				var strs = [];
				for(var index in obj) {
					strs.push(obj[index][scope.showKey]);
				}
				text = strs.join(scope.separator);
			} else {
				text = obj[scope.showKey]
			}
			return text;
		}
		this.showObj = function(scope) {
			var deferred = $q.defer();
			var obj = {};
			if(scope.multiple) {
				if(angular.isString(scope.model)) {
					obj[scope.valKey] = scope.model.split(scope.separator);
				} else if(angular.isArray(scope.model)) {
					obj[scope.valKey] = scope.model;
				}
			} else {
				obj[scope.valKey] = scope.model;
			}
			var arg = $.extend(true, {}, scope.args, obj);
			if(scope.url) {
				var url = "";
				if(scope.url.indexOf('.do') >= 0) {
					if(!scope.multiple) {
						url = scope.url.substr(0, scope.url.indexOf('.do')) + '/' + scope.valKey + '/' + scope.model + (scope.url.substr(scope.url.indexOf('.do')));
					} else {
						url = scope.url.substr(0, scope.url.indexOf('.do')) + '/' + scope.valKey + (scope.url.substr(scope.url.indexOf('.do')));
					}
				} else if(scope.url.index('?') >= 0) {
					if(!scope.multiple) {
						url = scope.url.substr(0, scope.url.indexOf('?')) + '/' + scope.valKey + '/' + scope.model + (scope.url.substr(scope.url.indexOf('?')));
					} else {
						url = scope.url.substr(0, scope.url.indexOf('?')) + '/' + scope.valKey + (scope.url.substr(scope.url.indexOf('?')));
					}
				} else {
					if(!scope.multiple) {
						url = scope.url + '/' + scope.valKey + '/' + scope.model;
					} else {
						url = scope.url + '/' + scope.valKey;
					}
				}
				httpWrapService.post(url, arg).then(function(res){
					if(res.data && (res.data.data || res.data.entity)) {
						if(res.data.entity) {
							deferred.resolve(res.data.entity);
						} else if(res.data.data) {
							deferred.resolve(res.data.data);
						}
					}
				});
			}
			return deferred.promise;
		}
		
	}]);

angular.module('app')
.controller('AppUiSelectController', ['$scope', "$element", "$attrs", 'AppUiService', function($scope, $element, $attrs, AppUiService){
	var ctrl = this;
	$scope.data = [];
	var multiple = $attrs.multiple;	// 多选
	multiple = $scope.multiple = angular.isDefined(multiple) ? (multiple === 'false' ? false : true ) : false;
	$scope.isArray = angular.isDefined($attrs.array) ? ($attrs.array === 'false' ? false : true ) : false;
	$scope.unWatch = angular.isDefined($attrs.unwatch) ? ($attrs.unwatch === 'true' ? true : false ) : false;
	$scope.selected = $scope.multiple ? [] : null;	// 被选中的数据，默认留空
	$scope.resetSearchInput = ($scope.uiResetSearchInput && $scope.uiResetSearchInput === 'true') ? true : false;
	if($scope.multiple) {
		$scope.closeOnSelect = ($scope.closeOnSelect && $scope.closeOnSelect === 'true') ? true : false;
	} else {
		$scope.closeOnSelect = ($scope.closeOnSelect && $scope.closeOnSelect === 'false') ? false : true;
	}
	
	var separator = $scope.separator = ($scope.separator) ? $scope.separator : ',';
	var showKey = $scope.showKey = ($scope.showProperty) ? $scope.showProperty : 'name';
	var valKey = $scope.valKey = ($scope.valProperty) ? $scope.valProperty : 'id';
	
	if($scope.watchFlush) {
		$scope.$parent.$watch($scope.watchFlush, function(newValue){
			if(!newValue) return;	// 级联查询没有值时，先不查询
			ctrl.load();
		});
	}
	
	this.load = function(){
		AppUiService.getDatas($scope).then(function(data){
			 $scope.data = data;
			 
			 if(!multiple) {
				 // 初始化
				// 监听首次赋值
				 var unModelWatch = $scope.$watch('model',function(newValue, oldValue){
					 if(newValue) {
						 $scope.uiObj = $scope.selected = AppUiService.initModel($scope);
						 if(!$scope.unWatch) {
							 unModelWatch();
						 }
					 } else {
						 $scope.uiObj = $scope.selected = null;
					 }
				 });
				 
				 // 监听变化
				 $scope.$watch('selected',function(newValue, oldValue){
					 if(newValue !== oldValue) {
						 $scope.model = (newValue) ? newValue[valKey] : null;
						 $scope.uiObj = newValue;
					 }
				 });
			 } else {
				 // 初始化
				 // 监听首次赋值
				 var unModelWatch = $scope.$watch('model',function(newValue, oldValue){
					 if(newValue) {
						 $scope.uiObj = $scope.selected = AppUiService.initModel($scope);
						 if(!$scope.unWatch) {
							 unModelWatch();
						 }
					 } else {
						 $scope.uiObj = $scope.selected = [];
					 }
				 });
				 
				 // 监听变化
				 $scope.$watchCollection('selected',function(newValue, oldValue){
					 if(newValue !== oldValue) {
						 if(!$scope.uiObj) $scope.uiObj = [];
						 // 未设置新值，直接返回
						 if(!newValue) {
							 $scope.model = null;
							 return ;
						 }
						 
						 var strVal = [];
						 for(var index in newValue) {
							 var row = newValue[index];
							 strVal.push(row[valKey]);
						 }
						 if($scope.isArray) {
							 $scope.model = strVal;
						 } else {
							 $scope.model = strVal.join(",");
						 }
						 $scope.uiObj = newValue;
					 }
				 });
			 }
		});
	}
	
	// 不是级联查询时，装载数据
	if(!$scope.watchFlush) {
		ctrl.load();
	}
	
}]);

angular.module('app')
.controller('AppShowController', ['$scope', "$element", "$attrs", 'AppUiService', function($scope, $element, $attrs, AppUiService){
	$scope.data = [];
	$scope.showApp = true;
	var multiple = $attrs.multiple;	// 多选
	multiple = $scope.multiple = angular.isDefined(multiple) ? (multiple === 'false' ? false : true ) : false;
	$scope.isArray = angular.isDefined($attrs.array) ? ($attrs.array === 'false' ? false : true ) : false;
	if(multiple){
		$scope.data = []
	} else {
		$scope.data = null;
	}
	
	var separator = $scope.separator = ($scope.separator) ? $scope.separator : ',';
	var showKey = $scope.showKey = ($scope.showProperty) ? $scope.showProperty : 'name';
	var valKey = $scope.valKey = ($scope.valProperty) ? $scope.valProperty : 'id';
	
	if(!multiple) {
		 // 初始化
		// 监听首次赋值
		 var unModelWatch = $scope.$watch('model',function(newValue, oldValue){
			 if(newValue && !$scope.uiObj) {
				 AppUiService.showObj($scope).then(function(obj){
					 $scope.uiObj = obj;
					 $scope.showText = AppUiService.showText($scope, obj);
				 });
				 unModelWatch();
			 }
		 });
		 
	 } else {
		 // 初始化
		 // 监听首次赋值
		 var unModelWatch = $scope.$watch('model',function(newValue, oldValue){
			 if(newValue && !(angular.isDefined($scope.uiObj) && $scope.uiObj.length > 0) ) {
				 AppUiService.showObj($scope).then(function(obj){
					 $scope.uiObj = obj;
					 $scope.showText = AppUiService.showText($scope, obj);
				 });
				 unModelWatch();
			 }
		 });
	 }
}]);

angular.module('app')
.directive('appShow', ['$timeout', '$parse', 'uiLoad', 'JQ_CONFIG', function ($timeout, $parse, uiLoad, JQ_CONFIG) { // 单选
	return {
		restrict : "A",
		template : "{{showText}}",
		controller : "AppShowController",
		scope : {
			model : '=appShow', 			// 绑定的外部数据model
			uiObj : '=?uiObj', 				// 绑定的外部数据model
			valProperty : "@property", 			// 设定值时使用的字段,默认为id
			showProperty : "@showProperty", 	// 显示值时使用的字段 默认name
			separator : "@separator", 			// 多个值分隔符
			array : "@array", 			// 多个值分隔符
			url : '@url', // 加载数据的URL
			args : '=args', // 请求参数
		},
		link : function($scope, element, attrs, ctrl) { // 控制器执行后执行link
			$(element).addClass('app-show');
		}
	}
}]);


angular.module('app')
.directive('appUiSelect', ['$timeout', '$parse', function ($timeout, $parse) { // 单选
	return {
		restrict : "A",
		templateUrl : function(tElement, tAttrs) {
			var multiple = tAttrs.multiple;
			multiple = angular.isDefined(multiple) ? (multiple === 'false' ? false : true ) : false;
			var murl = '';
			if(multiple) murl = '-multiple';
			return 'tpl-common/directives/app-ui-select' + murl  + '.html';
		},
		scope : {
			model : '=?appUiSelect', 			// 绑定的外部数据model
			uiObj : '=?uiObj', 			// 绑定的外部数据model
			fieldName: '@fieldName', 			// 绑定到input的name
			searchEnabled : '@searchEnabled',
			placeholder: '@placeholder',			
			resetSearchInput: '@resetSearchInput',	// 是否在搜索的时候重置input的值
			closeOnSelect: '@closeOnSelect',
			valProperty : "@property", 			// 设定值时使用的字段,默认为id
			showProperty : "@showProperty", 	// 显示值时使用的字段 默认name
			separator : "@separator", 			// 多个值分隔符
			array : "@array", 					// 值是否为数组
			url : '@url', // 加载数据的URL
			args : '=args', // 请求参数
			dictType : '@dictType',
			watchFlush : '@watchFlush',
			disabled:'=disabled',
			unwatch:'@unwatch',				// 是否观察model变化， 默认不观察
			required: '@required'			// 是否必填
		},
		controller : "AppUiSelectController",	
		link : function($scope, element, attrs, ctrl) { // 控制器执行后执行link
			$(element).addClass('app-ui-select');
		}
	}
}]);

